/**
 * 错误服务
 * 提供统一的错误处理、错误上报和错误管理功能
 */
import ServiceRegistry from './ServiceRegistry.js';

/**
 * 错误级别枚举
 */
export const ErrorLevel = {
  DEBUG: 'debug',
  INFO: 'info',
  WARNING: 'warning',
  ERROR: 'error',
  CRITICAL: 'critical'
};

/**
 * 错误类型枚举
 */
export const ErrorType = {
  VALIDATION: 'validation',
  AUTHENTICATION: 'authentication',
  PERMISSION: 'permission',
  NETWORK: 'network',
  TIMEOUT: 'timeout',
  SERVER: 'server',
  CLIENT: 'client',
  RUNTIME: 'runtime',
  UNKNOWN: 'unknown'
};

/**
 * Lifeservice错误类
 * 扩展自原生Error，增加了更多的错误信息和上下文
 */
export class LifeserviceError extends Error {
  constructor(message, options = {}) {
    super(message);
    this.name = 'LifeserviceError';
    this.type = options.type || ErrorType.UNKNOWN;
    this.level = options.level || ErrorLevel.ERROR;
    this.code = options.code || null;
    this.status = options.status || null;
    this.timestamp = new Date().toISOString();
    this.data = options.data || {};
    this.stack = options.stack || this.stack;
    
    // 保留原始错误
    this.originalError = options.originalError || null;
    
    // 确保错误对象可序列化
    Error.captureStackTrace(this, this.constructor);
  }
  
  /**
   * 获取标准化的错误对象
   */
  toJSON() {
    return {
      name: this.name,
      message: this.message,
      type: this.type,
      level: this.level,
      code: this.code,
      status: this.status,
      timestamp: this.timestamp,
      data: this.data,
      stack: this.stack ? this.stack.split('\n') : null,
      originalError: this.originalError ? this.originalError.message : null
    };
  }
}

/**
 * 错误服务类
 */
class ErrorService {
  constructor(options = {}) {
    this.options = {
      // 全局错误处理器
      globalHandlers: true,
      // 是否上报错误
      reportErrors: true,
      // 上报URL
      reportUrl: '/api/errors',
      // 是否显示通知
      showNotifications: true,
      // 是否记录日志
      logErrors: true,
      // 是否忽略特定错误
      ignoreErrors: [],
      // 错误历史记录最大数量
      maxHistorySize: 100,
      // 错误上报重试次数
      retryAttempts: 3,
      // 重试间隔
      retryInterval: 1000,
      ...options
    };
    
    // 服务依赖
    this._serviceRegistry = null;
    this._notificationService = null;
    this._loggerService = null;
    this._apiService = null;
    
    // 错误历史记录
    this._errorHistory = [];
    
    // 错误处理器映射
    this._errorHandlers = new Map();
    
    // 是否已启动
    this._isBooted = false;
    
    // 初始化默认处理器
    this._initializeDefaultHandlers();
  }
  
  /**
   * 启动服务
   */
  async boot() {
    if (this._isBooted) {
      return this;
    }
    
    // 获取服务注册表
    this._serviceRegistry = ServiceRegistry.getInstance();
    
    // 注册全局错误处理器
    if (this.options.globalHandlers) {
      this.registerGlobalHandlers();
    }
    
    this._isBooted = true;
    return this;
  }
  
  /**
   * 注册全局错误处理器
   */
  registerGlobalHandlers() {
    // 处理未捕获的错误
    window.addEventListener('error', (event) => {
      this.handleError(event.error || new Error(event.message));
    });
    
    // 处理未捕获的Promise拒绝
    window.addEventListener('unhandledrejection', (event) => {
      this.handleError(event.reason || new Error('Unhandled Promise rejection'));
    });
    
    // Vue错误处理器（如果Vue可用）
    if (window.Vue) {
      window.Vue.config.errorHandler = (err, vm, info) => {
        this.handleError(err, {
          type: ErrorType.RUNTIME,
          data: { component: vm?.constructor?.name, info }
        });
      };
    }
  }
  
  /**
   * 初始化默认错误处理器
   */
  _initializeDefaultHandlers() {
    // 注册默认的错误处理器
    this.registerErrorHandler(ErrorType.VALIDATION, this._handleValidationError.bind(this));
    this.registerErrorHandler(ErrorType.AUTHENTICATION, this._handleAuthenticationError.bind(this));
    this.registerErrorHandler(ErrorType.PERMISSION, this._handlePermissionError.bind(this));
    this.registerErrorHandler(ErrorType.NETWORK, this._handleNetworkError.bind(this));
    this.registerErrorHandler(ErrorType.TIMEOUT, this._handleTimeoutError.bind(this));
    this.registerErrorHandler(ErrorType.SERVER, this._handleServerError.bind(this));
    this.registerErrorHandler(ErrorType.CLIENT, this._handleClientError.bind(this));
    this.registerErrorHandler(ErrorType.RUNTIME, this._handleRuntimeError.bind(this));
    this.registerErrorHandler(ErrorType.UNKNOWN, this._handleUnknownError.bind(this));
  }
  
  /**
   * 注册错误处理器
   */
  registerErrorHandler(errorType, handler) {
    if (typeof handler !== 'function') {
      console.warn(`Error handler for ${errorType} must be a function`);
      return false;
    }
    
    this._errorHandlers.set(errorType, handler);
    return true;
  }
  
  /**
   * 处理错误
   */
  async handleError(error, options = {}) {
    try {
      // 标准化错误对象
      const normalizedError = this._normalizeError(error, options);
      
      // 检查是否需要忽略该错误
      if (this._shouldIgnoreError(normalizedError)) {
        return normalizedError;
      }
      
      // 记录错误到历史
      this._recordError(normalizedError);
      
      // 根据错误类型调用相应的处理器
      const handler = this._errorHandlers.get(normalizedError.type);
      if (handler) {
        await handler(normalizedError);
      } else {
        await this._handleUnknownError(normalizedError);
      }
      
      // 记录日志
      if (this.options.logErrors) {
        this._logError(normalizedError);
      }
      
      // 显示通知
      if (this.options.showNotifications && this._shouldShowNotification(normalizedError)) {
        this._showNotification(normalizedError);
      }
      
      // 上报错误
      if (this.options.reportErrors && this._shouldReportError(normalizedError)) {
        this._reportError(normalizedError).catch(reportError => {
          console.error('Failed to report error:', reportError);
        });
      }
      
      return normalizedError;
    } catch (handlingError) {
      console.error('Error while handling error:', handlingError);
      return error;
    }
  }
  
  /**
   * 标准化错误对象
   */
  _normalizeError(error, options = {}) {
    if (error instanceof LifeserviceError) {
      // 已经是标准化的错误
      return error;
    }
    
    // 从axios错误中提取信息
    if (error.response || error.request) {
      const axiosError = error;
      const status = axiosError.response?.status;
      let type = ErrorType.NETWORK;
      let code = null;
      
      if (status === 401) {
        type = ErrorType.AUTHENTICATION;
      } else if (status === 403) {
        type = ErrorType.PERMISSION;
      } else if (status >= 400 && status < 500) {
        type = ErrorType.CLIENT;
      } else if (status >= 500) {
        type = ErrorType.SERVER;
      }
      
      code = axiosError.response?.data?.code || `HTTP_${status}`;
      
      return new LifeserviceError(
        axiosError.message || 'Network error',
        {
          type,
          level: ErrorLevel.ERROR,
          code,
          status,
          data: axiosError.response?.data || {},
          originalError: axiosError,
          ...options
        }
      );
    }
    
    // 处理原生Error
    return new LifeserviceError(
      error.message || 'Unknown error',
      {
        type: options.type || ErrorType.UNKNOWN,
        level: options.level || ErrorLevel.ERROR,
        code: options.code || null,
        data: options.data || {},
        stack: error.stack,
        originalError: error,
        ...options
      }
    );
  }
  
  /**
   * 检查是否应该忽略错误
   */
  _shouldIgnoreError(error) {
    return this.options.ignoreErrors.some(pattern => {
      if (typeof pattern === 'string') {
        return error.message.includes(pattern) || error.code === pattern;
      }
      if (pattern instanceof RegExp) {
        return pattern.test(error.message);
      }
      if (typeof pattern === 'function') {
        return pattern(error);
      }
      return false;
    });
  }
  
  /**
   * 记录错误到历史
   */
  _recordError(error) {
    this._errorHistory.unshift(error);
    
    // 限制历史记录大小
    if (this._errorHistory.length > this.options.maxHistorySize) {
      this._errorHistory = this._errorHistory.slice(0, this.options.maxHistorySize);
    }
  }
  
  /**
   * 记录错误日志
   */
  _logError(error) {
    const logger = this._getLoggerService();
    if (!logger) {
      return;
    }
    
    const logLevel = error.level in ErrorLevel ? error.level : ErrorLevel.ERROR;
    const errorData = error.toJSON();
    
    logger[logLevel === ErrorLevel.DEBUG ? 'debug' : 
           logLevel === ErrorLevel.INFO ? 'info' :
           logLevel === ErrorLevel.WARNING ? 'warning' :
           logLevel === ErrorLevel.CRITICAL ? 'critical' : 'error'](
      error.message,
      {
        error: {
          type: error.type,
          code: error.code,
          status: error.status,
          data: error.data
        }
      }
    );
  }
  
  /**
   * 显示错误通知
   */
  _showNotification(error) {
    const notificationService = this._getNotificationService();
    if (!notificationService) {
      return;
    }
    
    const notificationType = error.level === ErrorLevel.WARNING ? 'warning' : 'error';
    const title = this._getErrorTitle(error);
    
    notificationService.notify({
      type: notificationType,
      title: title,
      message: error.message,
      duration: error.level === ErrorLevel.CRITICAL ? 10000 : 5000,
      meta: {
        errorType: error.type,
        errorCode: error.code
      }
    });
  }
  
  /**
   * 获取错误标题
   */
  _getErrorTitle(error) {
    switch (error.type) {
      case ErrorType.VALIDATION:
        return '验证错误';
      case ErrorType.AUTHENTICATION:
        return '认证失败';
      case ErrorType.PERMISSION:
        return '权限不足';
      case ErrorType.NETWORK:
        return '网络错误';
      case ErrorType.TIMEOUT:
        return '请求超时';
      case ErrorType.SERVER:
        return '服务器错误';
      case ErrorType.CLIENT:
        return '客户端错误';
      case ErrorType.RUNTIME:
        return '运行时错误';
      default:
        return '未知错误';
    }
  }
  
  /**
   * 上报错误
   */
  async _reportError(error) {
    const apiService = this._getApiService();
    const errorData = error.toJSON();
    
    try {
      if (apiService) {
        return await apiService.post(this.options.reportUrl, errorData);
      } else {
        // 如果没有API服务，尝试使用fetch
        const response = await fetch(this.options.reportUrl, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(errorData)
        });
        
        if (!response.ok) {
          throw new Error(`Error reporting failed: ${response.status}`);
        }
        
        return response.json();
      }
    } catch (error) {
      console.error('Error reporting failed:', error);
      throw error;
    }
  }
  
  /**
   * 检查是否应该上报错误
   */
  _shouldReportError(error) {
    return error.level >= ErrorLevel.ERROR;
  }
  
  /**
   * 检查是否应该显示通知
   */
  _shouldShowNotification(error) {
    return error.level >= ErrorLevel.WARNING;
  }
  
  /**
   * 获取通知服务
   */
  _getNotificationService() {
    if (!this._notificationService && this._serviceRegistry) {
      this._notificationService = this._serviceRegistry.get('notification');
    }
    return this._notificationService;
  }
  
  /**
   * 获取日志服务
   */
  _getLoggerService() {
    if (!this._loggerService && this._serviceRegistry) {
      this._loggerService = this._serviceRegistry.get('logger');
    }
    return this._loggerService;
  }
  
  /**
   * 获取API服务
   */
  _getApiService() {
    if (!this._apiService && this._serviceRegistry) {
      this._apiService = this._serviceRegistry.get('api');
    }
    return this._apiService;
  }
  
  /**
   * 获取错误历史
   */
  getErrorHistory() {
    return [...this._errorHistory];
  }
  
  /**
   * 清除错误历史
   */
  clearErrorHistory() {
    this._errorHistory = [];
  }
  
  /**
   * 处理验证错误
   */
  async _handleValidationError(error) {
    // 处理表单验证错误等
    console.warn('Validation error:', error);
  }
  
  /**
   * 处理认证错误
   */
  async _handleAuthenticationError(error) {
    // 处理认证失败，可能需要重定向到登录页面
    console.warn('Authentication error:', error);
    
    const authService = this._serviceRegistry?.get('auth');
    if (authService) {
      // 清除认证状态
      authService.logout();
      
      // 可以在这里重定向到登录页面
      const routerService = this._serviceRegistry?.get('router');
      if (routerService) {
        // routerService.push('/login');
      }
    }
  }
  
  /**
   * 处理权限错误
   */
  async _handlePermissionError(error) {
    // 处理权限不足
    console.warn('Permission error:', error);
  }
  
  /**
   * 处理网络错误
   */
  async _handleNetworkError(error) {
    // 处理网络连接错误
    console.warn('Network error:', error);
  }
  
  /**
   * 处理超时错误
   */
  async _handleTimeoutError(error) {
    // 处理请求超时
    console.warn('Timeout error:', error);
  }
  
  /**
   * 处理服务器错误
   */
  async _handleServerError(error) {
    // 处理服务器错误
    console.error('Server error:', error);
  }
  
  /**
   * 处理客户端错误
   */
  async _handleClientError(error) {
    // 处理客户端错误
    console.warn('Client error:', error);
  }
  
  /**
   * 处理运行时错误
   */
  async _handleRuntimeError(error) {
    // 处理运行时错误
    console.error('Runtime error:', error);
  }
  
  /**
   * 处理未知错误
   */
  async _handleUnknownError(error) {
    // 处理未知类型的错误
    console.error('Unknown error:', error);
  }
}

export default ErrorService;